package com.jiezuo.flowable.controller;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiezuo.common.base.BaseController;
import com.jiezuo.common.enums.ResultEnums;
import com.jiezuo.common.util.JsonUtils;
import com.jiezuo.common.util.ResultUtil;
import com.jiezuo.common.util.VerifyUtil;
import com.jiezuo.common.vo.PageVo;
import com.jiezuo.common.vo.Result;
import com.jiezuo.flowable.entity.*;
import com.jiezuo.flowable.service.UserTaskService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.task.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.*;

/**
 * @description 流程任务
 * @author 庞留杰
 * @date 2020/9/11 18:01
 * @version V1.0
 **/
@Slf4j
@Transactional
@RestController
@RequestMapping("/task")
public class UserTaskController extends BaseController {

    @Autowired
    private UserTaskService service;

    /**
     *  我的待办
     */
    @GetMapping("/backlog")
    public Result backlog(@ModelAttribute PageVo pageVo, @ModelAttribute TaskBacklogQuery backlogQuery) {
        Page page = service.backlog(pageVo, backlogQuery);
        return new ResultUtil<>().setData(page);
    }

    /**
     * 功能描述: 查询申请（查询我发起的流程实例）【对应表：act_hi_procinst 历史的流程实例表】
     * @author: 庞留杰
     * @param    taskDoingQuery
     * @return: Result
     * @exception
     * @date: 2020/9/16 17:44
     */
    @GetMapping("/doingPage")
    public Result doingPage(@ModelAttribute PageVo pageVo, @ModelAttribute TaskDoingQuery taskDoingQuery) {
        Page page = service.doingPage(pageVo, taskDoingQuery);
        return new ResultUtil<>().setData(page);
    }

    /**
     * 功能描述: 根据用户ID或者用户组ID，查询该用户代办，查询该用户代办数量
     * @author: 庞留杰
     * @param userId
     * @param groupIds
     * @return:
     * @exception
     * @date: 2021/4/15 11:23
     */
    @GetMapping("/count")
    public Result count(String userId, List<String> groupIds) {
        long count = service.count(userId, groupIds);
        return new ResultUtil<>().setData(count);
    }

    /**
     * 功能描述: 根据用户ID或者用户组ID，查询该用户待办
     * @author: 庞留杰
     * @param map
     *   businessKey: ""
     *   businessName: ""
     *   businessType: ""
     *   current: 1
     *   groupIds:  可能会很大，改成post请求
     *   size: 20
     *   userId: "admin"
     * @return:
     * @exception
     * @date: 2021/4/15 11:22
     */
    @PostMapping("/todoPage")
    public Result todoPage(@RequestBody Map<String, Object> map) {
        // @ModelAttribute PageVo pageVo, TaskToDoQuery query
        PageVo pageVo = JsonUtils.mapToObj(map, PageVo.class);
        TaskToDoQuery query = JsonUtils.mapToObj(map, TaskToDoQuery.class);
        Page page = service.todoPage(pageVo, query);
        return new ResultUtil<>().setData(page);
    }

    /**
     * 功能描述: 查询已办任务【对应表：act_hi_taskinst】
     * @author: 庞留杰
     * @param  taskDoneQuery
     * @return:
     * @exception
     * @date: 2020/9/14 9:14
     */
    //查询带分页列表", notes = "查询带分页列表")
    @GetMapping(value = "/donePage")
    public Result donePage(@ModelAttribute PageVo pageVo, TaskDoneQuery taskDoneQuery) {
        Page page = service.donePage(pageVo, taskDoneQuery);
        return new ResultUtil<>().setData(page);
    }

    /**
     * 功能描述: 执行任务
     *  任务执行类型 claim：签收 unclaim 反签收 complete 完成 delegate 任务委派 resolve 任务签收完成 返回任务人 assignee 任务转办
     * @author: 庞留杰
     * @param taskExecuteQuery
     * {
     *          taskId:'',
     *          action:"complete",
     *          localScope:false,
     *          assignee:"1",
     *          variables:{}
     * }
     * @return:
     * @exception
     * @date: 2021/4/15 11:03
     */
    @PostMapping(value = "executeTask")
    //任务执行类型 claim：签收 unclaim 反签收 complete 完成 delegate 任务委派 resolve 任务签收完成 返回任务人 assignee 任务转办
    public Result executeTask(@RequestBody TaskExecuteQuery taskExecuteQuery) {
        Map<String, Object> result = service.executeTask(taskExecuteQuery);
        return new ResultUtil<>().setData(result);
    }

    /**
     * 功能描述: 查询任务
     * @author: 庞留杰
     * @param taskListQuery
     * @return:
     * @exception
     * @date: 2021/4/15 11:06
     */
    //查询任务", notes = "查询任务")
    @GetMapping("/findTask")
    public Result findTask(TaskListQuery taskListQuery) {
        JSONArray arr = service.findTask(taskListQuery);
        return new ResultUtil<>().setData(arr);
    }

    /**
     * @description 添加备注信息
     * @param  commentAddQuery
     * {
     *        taskId: 任务ID
     *        processInstanceId:流程实例ID
     *        message: 批注信息
     *        userId: 用户ID
     * }
     * @author 庞留杰
     * @date 2020/9/14 9:34
     * @version V1.0
     **/
    @PostMapping(value = "/comment")
    public Result addComments(@RequestBody CommentAddQuery commentAddQuery) {
        service.addComments(commentAddQuery);
        return new ResultUtil<>().setSuccessMsg("添加批注信息成功");
    }

    /**
     * @description 添加备注信息 （不需要taskId，不能再并行网关中使用）
     * @param  commentAddQuery
     * {
     *        processInstanceId:流程实例ID
     *        message: 批注信息
     *        userId: 用户ID
     * }
     * @author 庞留杰
     * @date 2020/9/14 9:34
     * @version V2.0
     **/
    @PostMapping(value = "/v2/comment")
    public Result addComments2(@RequestBody CommentAddQuery commentAddQuery) {
        service.addComments2(commentAddQuery);
        return new ResultUtil<>().setSuccessMsg("添加批注信息成功");
    }


    /**
     * @description 查询备注信息
     * @param processInstanceId： 流程实例ID
     * @author 庞留杰
     * @date 2020/9/14 9:37
     * @version V1.0
     **/
    @GetMapping(value = "/findCommentList")
    public Result findCommentList(String processInstanceId) {
        List<Comment> comments = service.findCommentList(processInstanceId);
        return new ResultUtil<>().setData(comments);
    }

    /**
     * 功能描述: 获取所有可回退的节点
     * @author: 庞留杰
     * @param processInstanceId
     * @return:
     * @exception
     * @date: 2020/9/14 9:37
     */
    //获取所有可回退的节点", notes = "获取所有可回退的节点", produces = "application/json")
    @GetMapping(value = "/getFallbackNode/{processInstanceId}")
    public Result getFallbackNode(@PathVariable(value = "processInstanceId") String processInstanceId) {
        Map<String, Object> map = service.getFallbackNode(processInstanceId);
        return new ResultUtil<>().setData(map);
    }

    /**
     * 功能描述: 获取所有可回退的节点
     *          规则：
     *          1.从历史获取所有审批过的节点信息
     *          2.通过开始时间排序，去除历史中重复的节点
     * @author: 庞留杰
     * @param   processInstanceId
     * @return:
     * @exception
     * @date: 2021/1/21 15:10
     */
    //获取所有可回退的节点", notes = "获取所有可回退的节点", produces = "application/json")
    @GetMapping(value = "/v2/getFallbackNode/{processInstanceId}")
    public Result getFallbackNode2(@PathVariable(value = "processInstanceId") String processInstanceId) {
        Map<String, Object> map = service.getFallbackNode2(processInstanceId);
        return new ResultUtil<>().setData(map);
    }

    /**
     * 功能描述: 获取所有可回退的节点
     *          规则：
     *              从历史获取所有审批过的节点信息
     *              带分页
     * @author: 庞留杰
     * @param   processInstanceId
     * @return:
     * @exception
     * @date: 2021/1/21 15:10
     */
    //获取所有可回退的节点", notes = "获取所有可回退的节点", produces = "application/json")
    @GetMapping(value = "/v3/getFallbackNode/{processInstanceId}")
    public Result getFallbackNode3(@PathVariable(value = "processInstanceId") String processInstanceId, @ModelAttribute PageVo pageVo) {
        Map<String, Object> map = service.getFallbackNode3(processInstanceId, pageVo);
        return new ResultUtil<>().setData(map);
    }

    @GetMapping(value = "/v4/getFallbackNode")
    public Result getFallbackNode4(@RequestParam(required = true) String processInstanceId,@RequestParam(required = false) String taskId, @ModelAttribute PageVo pageVo) {
        Map<String, Object> map = service.getFallbackNode4(processInstanceId,taskId, pageVo);
        return new ResultUtil<>().setData(map);
    }

    /**
     * 功能描述: 任务撤回【注意：当前与目标定义Key为设计模板时任务对应的ID(通常格式：sid-xxxxxxxxxxxxxxxxx),而非数据主键ID】
     * @author: 庞留杰
     * @param taskFallbackQuery
     *         processInstanceId ：流程实例ID
     *         currentTaskKey ：当前任务定义Key
     *         targetTaskKey ：目标任务定义Key
     * @return:
     * @exception
     * @date: 2021/1/21 11:18
     */
    //任务撤回", notes = "任务撤回", produces = "application/json")
    @PostMapping("/withdraw")
    public Result withdraw(@RequestBody TaskFallbackQuery taskFallbackQuery) {
        service.withdraw(taskFallbackQuery);
        return new ResultUtil<>().setSuccessMsg("任务撤回成功");
    }

    /**
     * 功能描述: 退回上一步，注意只能回退一步【例： 当前在“第三步”：
     *                              调用一次，回退到“第二步”，
     *                              再次调用，回退到“第三步”，
     *                              再次调用，回退到“第二步”，
     *                                以此类推。。。。
     *           】
     * @author: 庞留杰
     * @param processInstanceId：流程实例ID
     * @return:
     * @exception
     * @date: 2021/1/21 11:20
     */
    @PostMapping("/rollback")
    public Result rollback(@RequestBody String processInstanceId) {
        Map<String, String> map = service.rollback(processInstanceId);
        return new ResultUtil<>().setData(map);
    }


    /**
     * 功能描述: 退回上一步，注意只能回退一步【例： 当前在“第三步”：
     *                              调用一次，回退到“第二步”，
     *                              再次调用，回退到“第三步”，
     *                              再次调用，回退到“第二步”，
     *                                以此类推。。。。
     *           】
     * @author: 庞留杰
     * @param map
     *            processInstanceId：流程实例ID
     *            previousActivityId：上一步任务的节点id（刚刚执行过的）
     * @return:
     * @exception
     * @date: 2021/1/21 11:20
     */
    @PostMapping("/v2/rollback")
    public Result rollback2(@RequestBody Map<String, Object> map) {
        Map<String, String> result = service.rollback2(map);
        return new ResultUtil<>().setData(result);
    }

    /**
     * 功能描述: 审批历史记录, 查看任务执行的详情【对应表：act_hi_actinst历史节点表】
     * @author: 庞留杰
     * @param  processInstanceId:流程实例ID
     * @return:
     * @exception
     * @date: 2020/9/16 19:38
     */
    @GetMapping(value = "/records")
    public Result records(@ModelAttribute PageVo pageVo, @RequestParam(value = "processInstanceId") String processInstanceId, @RequestParam(required = false) String executionId) {
        VerifyUtil.notEmpty("流程实例ID", processInstanceId);
        Page page = service.records(pageVo, processInstanceId, executionId);
        return new ResultUtil<>().setData(page);
    }


    //通过流程实例id获取taskId", notes = "通过流程实例id获取taskId")
    @GetMapping("/getTaskIdByProcessInstanceId")
    public Result getTaskIdByProcessInstanceId(@RequestParam(value = "processInstanceId") String processInstanceId) {
        String taskId = service.getTaskIdByProcessInstanceId(processInstanceId);
        return new ResultUtil<>().setData(taskId);
    }


    //加签", notes = "加签")
    @PostMapping("/addMultiInstance")
    public Result addMultiInstance(@RequestBody Map map) {
        service.addMultiInstance(map);
        return new ResultUtil<>().setSuccessMsg(ResultEnums.OK.getReasonPhraseCN());
    }


    //减签", notes = "减签")
    @PostMapping("/deleteMultiInstance")
    public Result deleteMultiInstance(@RequestBody Map map) {
        service.deleteMultiInstance(map);
        return new ResultUtil<>().setSuccessMsg(ResultEnums.OK.getReasonPhraseCN());
    }

    //通过流程实例id判断流程是否结束", notes = "通过流程实例id判断流程是否结束")
    @GetMapping("/isCompletedByProcessInstanceId")
    public Result isCompletedByProcessInstanceId(@RequestParam(value = "processInstanceId") String processInstanceId) {
        boolean boo = service.isCompletedByProcessInstanceId(processInstanceId);
        return new ResultUtil<>().setData(boo);
    }

}
